package com.szwistar.common.comm;

import org.apache.mina.core.buffer.IoBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ModbusRtuCmd extends ModbusRtuFrame implements AsyncCommand {
	protected static Logger LOG = LoggerFactory.getLogger(ModbusRtuCmd.class);
	protected static Logger LOGCOMM = LoggerFactory.getLogger("comm");

	// 重发次数
	protected int resendCount = 3;
	// 已经发送的次数
	protected int resentCount = 0;
	// 重发间隔(ms)
	protected int resendInterval = 3000;
	// 本消息的发送者
	protected AsyncTranceiver sender;

	@Override
	public void setResendCount(int resendCount) { this.resendCount = resendCount; }
	@Override
	public int getResendCount() { return resendCount; }
	@Override
	public void setResendInterval(int resendInterval) { this.resendInterval = resendInterval; }
	@Override
	public int getResendInterval() { return resendInterval; }
	@Override
	public int getResentCount() { return resentCount; }
	@Override
	public int increaseResentCount() { return ++resentCount; }
	@Override
	public AsyncTranceiver getSender() { return sender; }
	@Override
	public void setSender(AsyncTranceiver sender) { this.sender = sender; }

	@Override
	public Object getSource() { return (sender == null) ? null : sender.getOwner(); }
	@Override
	public Object getTarget() { return (sender == null) ? null : sender.getOwner(); }

	public short regStart; 	// 寄存器起始地址(高位在前，低位在后)
	public short regCount;	// 寄存器个数(高位在前，低位在后)
	public short shorts[];	// 数据(16位)
	public byte bytes[];	// 数据(字节)
	public int crc;			// MODBUS-CRC16(低位字节在前，高位字节在后)

	public ModbusRtuCmd(byte addr, byte func, short regStart, short regCount, short[] shorts, byte[] bytes) {
		super();
		this.addr = addr;
		this.func = func;
		this.regStart = regStart;
		this.regCount = regCount;
		this.shorts = shorts;
		this.bytes = bytes;
	}

	public IoBuffer encode() {
		IoBuffer buf = IoBuffer.allocate(20);

		buf.put(addr);
		buf.put(func);
		buf.putShort(regStart);
		buf.putShort(regCount);

		if(shorts != null) {
			buf.put((byte)(shorts.length*2));
			for(short v: shorts) { buf.putShort(v); }
		} else if(bytes != null) {
			buf.put((byte)(bytes.length));
			for(byte v: bytes) { buf.put(v); }
		}

		crc = getCRC(buf, 0, buf.position());
		buf.putShort((short)crc);
		buf.flip();

		LOGCOMM.debug("MODBUS数据帧编码输出：\n\t[{}]", buf.getHexDump());
		return buf;
	}

	@Override
	public boolean matchResponse(Object message) {
		if(message instanceof ModbusRtuAck) {
			return ((ModbusRtuAck)message).getSequence() == getSequence();
		}
		return false;
	}
}
